Load necessary packages, load data.
#load necessary packages:
library(car)
library(tidyverse)
library(caret)
library(multiUS)
library(boot)
library(ggplot2)
library(ggpubr)
library(readr)
library(corrplot)
library(olsrr)
library(MASS)
library(car)
#Load Data
data=read.csv('https://raw.githubusercontent.com/anishkapeter/Stat1Project/main/train.csv')
Fill missing values in numeric columns with KNN imputation
numeric_cols <- names(data)[sapply(data, is.numeric)]
#colSums(is.na(data[,numeric_cols]))
#mode(data$LotFrontage)
categorical_cols <- names(data)[sapply(data, is.character)]
#length(categorical_cols)+length(numeric_cols)
numeric_data <- data[, numeric_cols]
numeric_data_imputed <- KNNimp(as.matrix(numeric_data)) # convert data frame to matrix for knnImpute
data[numeric_cols] <- numeric_data_imputed
combine training and test data together, for easier cleaning
url <- "https://github.com/anishkapeter/Stat1Project/blob/main/test.csv?raw=true"
test <- read.csv(url)
data_c <- subset(data, select = -c(SalePrice))
saleprice = data$SalePrice
# Combine the data and test dataframes
combined_data <- rbind(data_c, test)
Define ordinal columns, regroup character columns and apply factor
encoding.
# Identify character columns
combined_data$ExterCond <- factor(combined_data$ExterCond, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$ExterCond <- as.numeric(combined_data$ExterCond)
combined_data$ExterQual <- factor(combined_data$ExterQual, levels = c("Fa", "TA", "Gd", "Ex"))
combined_data$ExterQual <- as.numeric(combined_data$ExterQual)
# First, ensure NA values are not treated as missing data
combined_data$BsmtQual <- addNA(combined_data$BsmtQual)
combined_data$BsmtCond <- addNA(combined_data$BsmtCond)
combined_data$BsmtQual <- factor(combined_data$BsmtQual, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$BsmtCond <- factor(combined_data$BsmtCond, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$BsmtQual <- as.numeric(combined_data$BsmtQual)
combined_data$BsmtCond <- as.numeric(combined_data$BsmtCond)
# First, ensure NA values are not treated as missing data
combined_data$GarageCond <- addNA(combined_data$GarageCond)
combined_data$GarageQual <- addNA(combined_data$GarageQual)
combined_data$GarageCond <- factor(combined_data$GarageCond, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$GarageQual <- factor(combined_data$GarageQual, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$GarageCond <- as.numeric(combined_data$GarageCond)
combined_data$GarageQual <- as.numeric(combined_data$GarageQual)
# Convert NA values to factor levels
combined_data$PoolQC <- addNA(combined_data$PoolQC)
combined_data$FireplaceQu <- addNA(combined_data$FireplaceQu)
combined_data$HeatingQC <- addNA(combined_data$HeatingQC)
combined_data$KitchenQual <- addNA(combined_data$KitchenQual)
combined_data$BsmtExposure <- addNA(combined_data$BsmtExposure)
combined_data$PoolQC <- factor(combined_data$PoolQC, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$FireplaceQu <- factor(combined_data$FireplaceQu, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$HeatingQC <- factor(combined_data$HeatingQC, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$KitchenQual <- factor(combined_data$KitchenQual, levels = c("Po", "Fa", "TA", "Gd", "Ex"))
combined_data$BsmtExposure <- factor(combined_data$BsmtExposure, levels = c("No", "Mn", "Av", "Gd"))
combined_data$PoolQC <- as.numeric(combined_data$PoolQC)
combined_data$FireplaceQu <- as.numeric(combined_data$FireplaceQu)
combined_data$HeatingQC <- as.numeric(combined_data$HeatingQC)
combined_data$KitchenQual <- as.numeric(combined_data$KitchenQual)
combined_data$BsmtExposure <- as.numeric(combined_data$BsmtExposure)
# Convert NA values to factor levels
combined_data$BsmtFinType1 <- addNA(combined_data$BsmtFinType1)
combined_data$BsmtFinType2 <- addNA(combined_data$BsmtFinType2)
combined_data$Fence <- addNA(combined_data$Fence)
combined_data$GarageFinish <- addNA(combined_data$GarageFinish)
combined_data$Alley <- addNA(combined_data$Alley)
#table(combined_data$Alley)
combined_data$BsmtFinType1 <- factor(combined_data$BsmtFinType1, levels = c("Unf", "LwQ", "Rec", "BLQ", "ALQ", "GLQ"))
combined_data$BsmtFinType2 <- factor(combined_data$BsmtFinType2, levels = c("Unf", "LwQ", "Rec", "BLQ", "ALQ", "GLQ"))
combined_data$CentralAir <- factor(combined_data$CentralAir, levels = c("N", "Y"))
combined_data$Fence <- factor(combined_data$Fence, levels = c("MnWw", "GdWo", "MnPrv", "GdPrv"))
combined_data$GarageFinish <- factor(combined_data$GarageFinish, levels = c("Unf", "RFn", "Fin"))
combined_data$Alley <- factor(combined_data$Alley, levels = c("Grvl", "Pave"))
combined_data$LotShape <- factor(combined_data$LotShape, levels = c("Reg", "IR1", "IR2", "IR3"))
combined_data$LandSlope <- factor(combined_data$LandSlope, levels = c("Gtl", "Mod", "Sev"))
combined_data$BsmtFinType1 <- as.numeric(combined_data$BsmtFinType1)
combined_data$BsmtFinType2 <- as.numeric(combined_data$BsmtFinType2)
combined_data$CentralAir <- as.numeric(combined_data$CentralAir)
combined_data$Fence <- as.numeric(combined_data$Fence)
combined_data$GarageFinish <- as.numeric(combined_data$GarageFinish)
combined_data$Alley <- as.numeric(combined_data$Alley)
combined_data$LotShape <- as.numeric(combined_data$LotShape)
combined_data$LandSlope <- as.numeric(combined_data$LandSlope)
ordinal_cols <- c('ExterQual', 'ExterCond', 'BsmtQual', 'BsmtCond',
'GarageCond', 'GarageQual', 'PoolQC', 'FireplaceQu',
'HeatingQC', 'KitchenQual', 'BsmtExposure', 'BsmtFinType1',
'BsmtFinType2', 'CentralAir', 'Fence','GarageFinish','Alley','LotShape','LandSlope')
#table(data$ExterQual)
combined_data[ordinal_cols] <- lapply(combined_data[ordinal_cols], function(x) replace(x, is.na(x), 0))
# Transform ordinal columns into factors and replace NA with 0
#data[ordinal_cols] <- lapply(data[ordinal_cols], function(x) {
# x <- as.factor(x)
# levels(x) <- c(levels(x), "0")
# x[is.na(x)] <- "0"
# return(x)
# })
# Checking all character columns
#colnames(data)[colSums(is.na(data)) > 0]
# Threshold for 'rare' observations
n <- 10
# Loop through the character columns
for (col_name in colnames(combined_data)[sapply(combined_data, is.character)]) {
# Convert rare observations to 'Other'
combined_data[[col_name]] <- ifelse(combined_data[[col_name]] %in% names(which(table(combined_data[[col_name]]) < n)), "Other", combined_data[[col_name]])
# Convert column to factor
combined_data[[col_name]] <- as.factor(combined_data[[col_name]])
# Add NA as a level if there are any NAs in the column
if(any(is.na(combined_data[[col_name]]))) {
combined_data[[col_name]] <- addNA(combined_data[[col_name]])
}
}
#Deleting some columns
#rare_level_factors <- sapply(data2, function(x) is.factor(x) && any(table(x) <= 2))
#print(names(data2)[rare_level_factors])
#data$Electrical=as.character(data$Electrical)
#data$Electrical[is.na(data$Electrical)] <- "Other"
#data$Electrical=as.factor(data$Electrical)
#class(combined_data$Electrical)
#data <- data[,-which(names(data) == "Utilities")]
# No more missing values, ordinary variable has been factorized
sum(is.na(combined_data))
#table(data$MiscFeature)
#table(data$Street)
#table(data$Utilities)
#table(data$Condition2)
#table(data$MiscFeature)
#table(data$Electrical)
Checking Colinearity of the model
#Deleting "TotalBsmtSF or X1stFlrSF" , "GarageCars or GarageArea" , "YearBuilt or GarageYearBuilt" , "Fireplaces" or "FireplacesQu" , "GarageCond" or GarageQu", "PoolQC or PoolArea"
df_numeric <- combined_data[sapply(combined_data, is.numeric)]
# Compute the correlation matrix
cor_matrix <- cor(df_numeric, use = "pairwise.complete.obs")
# Create a correlation plot
corrplot(cor_matrix, type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45, tl.cex = 0.5)
# Find pairs with high correlation
high_corr_indices <- findCorrelation(cor_matrix, cutoff = 0.7)
# Get column names from indices
high_corr_names <- colnames(df_numeric)[high_corr_indices]
# Print the column names
print(high_corr_names)
Deleting “TotalBsmtSF or X1stFlrSF” , “GarageCars or GarageArea” ,
“YearBuilt or GarageYearBuilt” , “Fireplaces” or “FireplacesQu” ,
“GarageCond” or GarageQual” “PoolQC or PoolArea”, “BsmtFinSF1 or
BsmtFinType1”, “BsmtFinSF2 or BsmtFinType2”
Checking for redundency/ deleting noise in the data
Rare Observation provide very little information about the dependent
variable and may cause noise in the data set.
table(combined_data$Street)
table(combined_data$Utilities)
table(combined_data$Condition2)
table(combined_data$MiscFeature)
combined_data <- combined_data[, -which(names(combined_data) %in% c('X1stFlrSF', 'GarageCars', 'GarageYrBlt','FireplaceQu','GarageCond','PoolQC','BsmtFinType1','BsmtFinType2' ,'Street', 'Utilities', 'Condition2', 'MiscFeature', 'Alley','Fence'))]
#write.csv(data2,file = 'data2')
#formula(model2)
#colnames(data2[sapply(data2,is.numeric)])
table(combined_data$Foundation)
Checking assumption for regression (full model)
data=combined_data[1:1460,]
data$SalePrice=saleprice
test = combined_data[1461:nrow(combined_data), ]
model = lm(SalePrice ~., data = data)
# residual plots / Histogram / Q-Q plot / Calculate Cook's distances /Create Residuals vs Leverage plot
histogram(model$residuals)
plot(model)
#Look for influential observations
#Looking at observation 1299,524, delete them in the data
data= data[-c(1299,524),]
rownames(data) <- NULL
#write.csv(data,file = "train123")
#colnames(data[sapply(combined_data, is.factor)])
Logging SalePrice to see if it fix the clusterred residuals
data2=data
data2$SalePrice = log(data$SalePrice)
model2 = lm(SalePrice~., data = data2)
#summary(model2)
residualPlot(model2)
#write.csv(data2,file="logdata.csv",row.names = FALSE)
# Compare to model1(unlogged) , the residual plots forms a rather perfect random cloud formation which is ideal
# Histogram
res2= model2$residuals
histogram(res2)
plot(model2)
Build custom regression model in SAS
model_formula= lm(SalePrice ~ MSZoning:GrLivArea+ LotArea:BsmtFinSF1+KitchenAbvGr:GarageQual +GrLivArea:LotArea+ LotArea + OverallQual + OverallCond + YearBuilt + BsmtExposure + BsmtFinSF1 +BsmtFinSF2 +HeatingQC+BsmtUnfSF + GrLivArea + HalfBath + KitchenAbvGr + KitchenQual + GarageArea + GarageQual + WoodDeckSF +
ScreenPorch + MSZoning + Neighborhood + BldgType +
MasVnrType + Foundation + Functional + GarageType + SaleCondition+Fireplaces,
data = data2)
Predition
table(data$MSZoning)
table(test$MSZoning)
levels(test$MSZoning)[is.na(levels(test$MSZoning))] <- "RL"
table(data$Exterior1st )
table(test$Exterior1st )
levels(test$Exterior1st)[is.na(levels(test$Exterior1st))] <- "VinylSd"
table(data$Functional )
table(test$Functional )
levels(test$Functional )[is.na(levels(test$Functional ))] <- "Typ"
table(data$SaleType )
table(test$SaleType )
levels(test$SaleType )[is.na(levels(test$SaleType ))] <- "WD"
#Forward
lm_predict_model= lm(SalePrice ~ MSSubClass + LotArea + OverallQual + OverallCond + YearBuilt + MasVnrArea + ExterQual +
BsmtQual + BsmtCond + BsmtExposure + BsmtFinSF1 + TotalBsmtSF + GrLivArea + HalfBath +
BedroomAbvGr + KitchenAbvGr + KitchenQual + GarageArea + GarageQual + WoodDeckSF +
ScreenPorch + MoSold + MSZoning + LotConfig + Neighborhood + Condition1 + BldgType +
Exterior1st + MasVnrType + Foundation + Functional + GarageType + PavedDrive + SaleCondition,
data = data2)
#summary(lm_predict_model)
prediciton=predict(lm_predict_model,newdata = test)
test$SalePrice=exp(prediciton)
Submission_F=test[,c("Id","SalePrice")]
mean_sale_price <- mean(Submission_F$SalePrice, na.rm = TRUE)
Submission_F$SalePrice[is.na(Submission_F$SalePrice)] <- mean_sale_price
sum(is.na(prediciton))
write.csv(Submission_F, file = 'Submission_F.csv', row.names = FALSE)
plot(lm_predict_model$residuals)
qqPlot(lm_predict_model)
histogram(lm_predict_model$residuals)
plot(lm_predict_model)
#Backward
model_formula <- lm( SalePrice ~ MSSubClass + LotFrontage + LotArea + LandSlope + OverallQual + OverallCond + YearBuilt + MasVnrArea + ExterQual + ExterCond + BsmtQual + BsmtCond + BsmtExposure + BsmtFinSF1 + BsmtFinSF2 + BsmtUnfSF + HeatingQC + X2ndFlrSF + LowQualFinSF + GrLivArea + FullBath + HalfBath + BedroomAbvGr + KitchenAbvGr + KitchenQual + TotRmsAbvGrd + Fireplaces + GarageArea + GarageQual + WoodDeckSF + OpenPorchSF + X3SsnPorch + ScreenPorch + PoolArea + MoSold + MSZoning + LandContour + LotConfig + Neighborhood + Condition1 + BldgType + HouseStyle + RoofMatl + Exterior1st + MasVnrType + Foundation + Functional + GarageType + SaleType + SaleCondition
,data = data2)
#summary(model_formula)
prediciton=predict(model_formula,newdata = test)
test$SalePrice=exp(prediciton)
submission_Backward=test[,c("Id","SalePrice")]
mean_sale_price <- mean(submission_Backward$SalePrice, na.rm = TRUE)
submission_Backward$SalePrice[is.na(submission_Backward$SalePrice)] <- mean_sale_price
sum(is.na(prediciton))
write.csv(submission_Backward, file = 'submission_Backward.csv', row.names = FALSE)
plot(model_formula$residuals)
qqPlot(model_formula)
histogram(model_formula$residuals)
plot(model_formula)
#stepwise
model_formula <- lm(SalePrice ~ MSSubClass + LotFrontage + LotArea + LandSlope + OverallQual + OverallCond + YearBuilt + MasVnrArea + ExterQual + ExterCond + BsmtQual + BsmtCond + BsmtExposure + BsmtFinSF1 + BsmtFinSF2 + TotalBsmtSF + GrLivArea + BedroomAbvGr + KitchenAbvGr + KitchenQual + GarageArea + GarageQual + WoodDeckSF + OpenPorchSF + MoSold + MSZoning + LotConfig + Neighborhood + Condition1 + BldgType + Exterior1st + MasVnrType + Functional + GarageType + PavedDrive + SaleCondition,data = data2)
#summary(model_formula)
prediciton=predict(model_formula,newdata = test)
test$SalePrice=exp(prediciton)
submission_stepwise=test[,c("Id","SalePrice")]
mean_sale_price <- mean(submission_stepwise$SalePrice, na.rm = TRUE)
submission_stepwise$SalePrice[is.na(submission_stepwise$SalePrice)] <- mean_sale_price
sum(is.na(prediciton))
write.csv(submission_stepwise, file = 'submission_stepwise.csv', row.names = FALSE)
plot(model_formula$residuals)
qqPlot(model_formula)
histogram(model_formula$residuals)
plot(model_formula)
#Custom
model_formula= lm(SalePrice ~ MSZoning:GrLivArea+ LotArea:BsmtFinSF1+KitchenAbvGr:GarageQual +GrLivArea:LotArea+ LotArea + OverallQual + OverallCond + YearBuilt + BsmtExposure + BsmtFinSF1 +BsmtFinSF2 +HeatingQC+BsmtUnfSF + GrLivArea + HalfBath + KitchenAbvGr + KitchenQual + GarageArea + GarageQual + WoodDeckSF +
ScreenPorch + MSZoning + Neighborhood + BldgType +
MasVnrType + Foundation + Functional + GarageType + SaleCondition+Fireplaces,
data = data2)
#summary(model_formula)
prediciton=predict(model_formula,newdata = test)
test$SalePrice=exp(prediciton)
submission_Cust=test[,c("Id","SalePrice")]
mean_sale_price <- mean(submission_Cust$SalePrice, na.rm = TRUE)
submission_Cust$SalePrice[is.na(submission_Cust$SalePrice)] <- mean_sale_price
sum(is.na(prediciton))
write.csv(submission_Cust, file = 'submission_Cust.csv', row.names = FALSE)
plot(model_formula)
plot(model_formula$residuals)
histogram(model_formula$residuals)
#trial2
model_formula= lm(SalePrice ~ (YearBuilt:ScreenPorch+LotArea:TotalBsmtSF+KitchenAbvGr:GarageQual +GrLivArea:LotArea+ LotArea + OverallQual + OverallCond + YearBuilt + BsmtExposure + BsmtFinSF1 +BsmtFinSF2 +HeatingQC+BsmtUnfSF + GrLivArea + HalfBath + KitchenAbvGr + KitchenQual + GarageArea + GarageQual + WoodDeckSF +
ScreenPorch + MSZoning + Neighborhood + BldgType +
MasVnrType + Foundation + Functional + GarageType + SaleCondition+Fireplaces)^2,
data = data2)
#summary(model_formula)
prediciton=predict(model_formula,newdata = test)
test$SalePrice=exp(prediciton)
submission_Cust=test[,c("Id","SalePrice")]
mean_sale_price <- mean(submission_Cust$SalePrice, na.rm = TRUE)
submission_Cust$SalePrice[is.na(submission_Cust$SalePrice)] <- mean_sale_price
sum(is.na(prediciton))
write.csv(submission_Cust, file = 'submission_Cust.csv', row.names = FALSE)
Examen relationship in Sales price in neighborhood ‘NAmes’,
‘Edwards’, ‘BrkSide’
options(scipen = 999)
library(dplyr)
library(ggplot2)
data= read.csv("https://raw.githubusercontent.com/anishkapeter/Stat1Project/main/train.csv")
# Model without Interaction Variable
filtered_neighborhood = data %>% filter (Neighborhood %in% c('NAmes', 'Edwards', 'BrkSide'))
filtered_neighborhood_model= lm(SalePrice ~ GrLivArea, data = filtered_neighborhood)
#summary(filtered_neighborhood_model)
# Check Assumptions Model Without Indicator and Interaction Variable
plot(filtered_neighborhood_model)
histogram(filtered_neighborhood_model$residuals)
ggplot(filtered_neighborhood,aes(x =GrLivArea , y =SalePrice )) +
geom_point() +
ggtitle("ScatterPlot of SalePrice vs GrLivArea")
# Residual plot clustered, using log-log method to transform the dataset
# Log log Transform to data
data3=data
data3$SalePrice = log(data$SalePrice)
data3$GrLivArea = log(data$GrLivArea)
# filter the logged data to only include the 3 neighborhoods of interest
filtered_data2 <- data3 %>% filter(Neighborhood %in% c('NAmes', 'Edwards', 'BrkSide'))
# build model on log data without interaction and indicator var
filtered_data2_model = lm(SalePrice ~ GrLivArea, data = filtered_data2)
#summary(filtered_data2_model)
# Checking Assumptions
ggplot(filtered_data2,aes(x =GrLivArea , y =SalePrice )) +
geom_point()+ggtitle("ScatterPlot of Log(SalePrice) vs Log(GrLivArea)") +
xlab("Log(GrLivArea)") +
ylab("Log(SalePrice)")
hist(filtered_data2_model$residuals)
plot(filtered_data2_model)
# Confidence Interval for Log Model without Interaction or Indicator
confint(filtered_data2_model)
plot(filtered_data2$GrLivArea, filtered_data2$SalePrice,
main="Scatterplot with Regression Line",
xlab="Above grade (ground) living area square feet (GrLivArea)",
ylab="Sale Price (SalePrice)", pch=19, frame=FALSE, col="blue")+
abline(filtered_data2_model, col="red")
Therefore the regression model predicting SalePrice using GrlivArea
is
SalePrice = 7.58437 + 0.59230 * GrlivArea
Adding Indicator Variable
# Adding Indicator Variable
filtered_data2_model3 <- lm(SalePrice ~ GrLivArea + Neighborhood, data = filtered_data2)
#summary(filtered_data2_model3)
Adding interaction variables
# Fit the model
filtered_data2_model2 <- lm(SalePrice ~ GrLivArea + GrLivArea * Neighborhood, data = filtered_data2)
# Summary of the model
#summary(filtered_data2_model2)
# Confidence intervals
confint(filtered_data2_model2)
# Residuals histogram
histogram <- ggplot(filtered_data2_model2, aes(x=residuals)) +
geom_histogram(binwidth=1, color="black", fill="white") +
theme_minimal() +
labs(x="Residuals", y="Frequency", title="Histogram of Residuals")
# Model diagnostics
plot_diag <- plot(filtered_data2_model2, diagnostic = TRUE)
# Model Coefficients
model_coef <- coef(filtered_data2_model2)
Anova Analysis
#ANOVA for model with Neighborhood as Interaction Variable
anova(filtered_data2_model3)
#ANOVA for model with Neighborhood as Indicator Variable
anova(filtered_data2_model2)
#ANOVA for model without Neighborhood
anova(filtered_data2_model)
1 - pf(68.02972973,2,377)
1 - pf(8.641891892,2,377)
Model with Interaction Summaries
For our best performing model we had #1288 on Kaggle, Yah! 
For each neighborhood, the regression model predicting SalePrice
using GrLivArea is given by:
Neighborhood ‘BrkSide’:
logSalePrice = 5.91292 + 0.81965*logGrLivArea
Interpretation of the Coefficients
Every time the square footage of the living area doubles, there is an
estimated multiplicative increase of 1.76497775436 (about 76.5%
increase) in the median Sale Price.
When the square footage of the living area is 0, the estimated median
SalePrice 369.78435.
Interpretation of Confidence Intervals
Every time the square footage of the living area doubles, the
estimated multiplicative increase in median Sales Price for Brookeside
is between 1.60081478829 and 1.94597031156.
When the square footage of the living area is 0., the estimated
median Sale Price is between 137.10639085 and 997.332584908 in Brookside
neighborhood.
Neighborhood ‘NAmes’:
logSalePrice = 7.74784 + 0.47303*logGrLivArea
Interpretation of the Coefficients
Every time the square footage of the living area doubles, there is an
estimated multiplicative increase of 1.38802158181, (about 38.8%
increase) in the median Sale Price.
When the square footage of the living area is 0, the estimated median
SalePrice 4879.16803655.
Interpretation of Confidence Intervals
When the square footage of the living area is 0, the estimated median
SalePrice 4879.16803655 .
When the square footage of the living area is 0, the estimated median
Sale Price is between 556.146417272 and 42805.5779923 in North Ames
neighborhood.
Neighborhood ‘Edwards’:
logSalePrice = 8.00651 + 0.51967 *logGrLivArea
Interpretation of the Coefficients
Every time the square footage of the living area doubles, there is an
estimated multiplicative increase of 1.4336074105 (about 43.36%
increase) in the median Sale Price.
When the square footage of the living area is 0, the estimated median
Sale Price 3000.42732748.
Confidence Intervals and Interpretation
When the square footage of the living area is 0, the estimated median
Sale Price is between 312.416333335 and 28815.756004 for houses in the
Edwards Neighborhood.
Every time the square footage of the living area doubles, the
estimated multiplicative increase in median Sales Price for Edwards
Neighborhood is between 1.14827731299 and 1.78988066094.
filtered_data2 library(ggplot2) filtered_neighborhood %>%
filter(Neighborhood == “BrkSide”) %>% ggplot(aes(x=GrLivArea, y =
SalePrice)) + geom_point( color = “steelblue”) + ggtitle(“Sale Price vs
Living Area Sq.Ft in Brookside”) + xlab(“Square Footage of Living Area”)
+ ylab(“Sales Price in Dollars”)
filtered_neighborhood %>% filter(Neighborhood == “Edwards”) %>%
ggplot(aes(x=GrLivArea, y = SalePrice)) + geom_point( color =
“steelblue”) + ggtitle(“Sale Price vs Living Area Sq.Ft in Edwards”) +
xlab(“Square Footage of Living Area”) + ylab(“Sales Price in
Dollars”)
filtered_neighborhood %>% filter(Neighborhood == “NAmes”) %>%
ggplot(aes(x=GrLivArea, y = SalePrice)) + geom_point(color =
“steelblue”) + ggtitle(“Sale Price vs Living Area Sq.Ft in North Ames”)
+ xlab(“Square Footage of Living Area”) + ylab(“Sales Price in
Dollars”)
LS0tDQp0aXRsZTogIkhvdXNlUHJpY2UgUHJlZGljdGlvbiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQpkYXRlOiAiMjAyMy0wNy0zMCINCi0tLQ0KDQotLS0NCg0KIyBMb2FkIG5lY2Vzc2FyeSBwYWNrYWdlcywgbG9hZCBkYXRhLg0KDQpgYGB7Uix3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KI2xvYWQgbmVjZXNzYXJ5IHBhY2thZ2VzOg0KbGlicmFyeShjYXIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoY2FyZXQpDQpsaWJyYXJ5KG11bHRpVVMpDQpsaWJyYXJ5KGJvb3QpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGdncHVicikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShvbHNycikNCmxpYnJhcnkoTUFTUykNCmxpYnJhcnkoY2FyKQ0KDQoNCiNMb2FkIERhdGENCg0KZGF0YT1yZWFkLmNzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2FuaXNoa2FwZXRlci9TdGF0MVByb2plY3QvbWFpbi90cmFpbi5jc3YnKQ0KDQpgYGANCiMgRmlsbCBtaXNzaW5nIHZhbHVlcyBpbiBudW1lcmljIGNvbHVtbnMgd2l0aCBLTk4gaW1wdXRhdGlvbg0KYGBge3Isd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCm51bWVyaWNfY29scyA8LSBuYW1lcyhkYXRhKVtzYXBwbHkoZGF0YSwgaXMubnVtZXJpYyldDQojY29sU3Vtcyhpcy5uYShkYXRhWyxudW1lcmljX2NvbHNdKSkNCiNtb2RlKGRhdGEkTG90RnJvbnRhZ2UpDQoNCg0KY2F0ZWdvcmljYWxfY29scyA8LSBuYW1lcyhkYXRhKVtzYXBwbHkoZGF0YSwgaXMuY2hhcmFjdGVyKV0NCiNsZW5ndGgoY2F0ZWdvcmljYWxfY29scykrbGVuZ3RoKG51bWVyaWNfY29scykNCm51bWVyaWNfZGF0YSA8LSBkYXRhWywgbnVtZXJpY19jb2xzXQ0KbnVtZXJpY19kYXRhX2ltcHV0ZWQgPC0gS05OaW1wKGFzLm1hdHJpeChudW1lcmljX2RhdGEpKSAgIyBjb252ZXJ0IGRhdGEgZnJhbWUgdG8gbWF0cml4IGZvciBrbm5JbXB1dGUNCmRhdGFbbnVtZXJpY19jb2xzXSA8LSBudW1lcmljX2RhdGFfaW1wdXRlZA0KDQpgYGANCg0KDQojIGNvbWJpbmUgdHJhaW5pbmcgYW5kIHRlc3QgZGF0YSB0b2dldGhlciwgZm9yIGVhc2llciBjbGVhbmluZw0KDQpgYGB7cn0NCnVybCA8LSAiaHR0cHM6Ly9naXRodWIuY29tL2FuaXNoa2FwZXRlci9TdGF0MVByb2plY3QvYmxvYi9tYWluL3Rlc3QuY3N2P3Jhdz10cnVlIg0KdGVzdCA8LSByZWFkLmNzdih1cmwpDQoNCmRhdGFfYyA8LSBzdWJzZXQoZGF0YSwgc2VsZWN0ID0gLWMoU2FsZVByaWNlKSkNCnNhbGVwcmljZSA9IGRhdGEkU2FsZVByaWNlDQojIENvbWJpbmUgdGhlIGRhdGEgYW5kIHRlc3QgZGF0YWZyYW1lcw0KY29tYmluZWRfZGF0YSA8LSByYmluZChkYXRhX2MsIHRlc3QpDQoNCg0KDQpgYGANCg0KIyBEZWZpbmUgb3JkaW5hbCBjb2x1bW5zLCByZWdyb3VwIGNoYXJhY3RlciBjb2x1bW5zIGFuZCBhcHBseSBmYWN0b3IgZW5jb2RpbmcuDQpgYGB7cix3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KIyBJZGVudGlmeSBjaGFyYWN0ZXIgY29sdW1ucw0KDQoNCg0KY29tYmluZWRfZGF0YSRFeHRlckNvbmQgPC0gZmFjdG9yKGNvbWJpbmVkX2RhdGEkRXh0ZXJDb25kLCBsZXZlbHMgPSBjKCJQbyIsICJGYSIsICJUQSIsICJHZCIsICJFeCIpKQ0KY29tYmluZWRfZGF0YSRFeHRlckNvbmQgPC0gYXMubnVtZXJpYyhjb21iaW5lZF9kYXRhJEV4dGVyQ29uZCkNCmNvbWJpbmVkX2RhdGEkRXh0ZXJRdWFsIDwtIGZhY3Rvcihjb21iaW5lZF9kYXRhJEV4dGVyUXVhbCwgbGV2ZWxzID0gYygiRmEiLCAiVEEiLCAiR2QiLCAiRXgiKSkNCmNvbWJpbmVkX2RhdGEkRXh0ZXJRdWFsIDwtIGFzLm51bWVyaWMoY29tYmluZWRfZGF0YSRFeHRlclF1YWwpDQoNCg0KIyBGaXJzdCwgZW5zdXJlIE5BIHZhbHVlcyBhcmUgbm90IHRyZWF0ZWQgYXMgbWlzc2luZyBkYXRhDQpjb21iaW5lZF9kYXRhJEJzbXRRdWFsIDwtIGFkZE5BKGNvbWJpbmVkX2RhdGEkQnNtdFF1YWwpDQpjb21iaW5lZF9kYXRhJEJzbXRDb25kIDwtIGFkZE5BKGNvbWJpbmVkX2RhdGEkQnNtdENvbmQpDQpjb21iaW5lZF9kYXRhJEJzbXRRdWFsIDwtIGZhY3Rvcihjb21iaW5lZF9kYXRhJEJzbXRRdWFsLCBsZXZlbHMgPSBjKCJQbyIsICJGYSIsICJUQSIsICJHZCIsICJFeCIpKQ0KY29tYmluZWRfZGF0YSRCc210Q29uZCA8LSBmYWN0b3IoY29tYmluZWRfZGF0YSRCc210Q29uZCwgbGV2ZWxzID0gYygiUG8iLCAiRmEiLCAiVEEiLCAiR2QiLCAiRXgiKSkNCmNvbWJpbmVkX2RhdGEkQnNtdFF1YWwgPC0gYXMubnVtZXJpYyhjb21iaW5lZF9kYXRhJEJzbXRRdWFsKQ0KY29tYmluZWRfZGF0YSRCc210Q29uZCA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkQnNtdENvbmQpDQoNCg0KDQojIEZpcnN0LCBlbnN1cmUgTkEgdmFsdWVzIGFyZSBub3QgdHJlYXRlZCBhcyBtaXNzaW5nIGRhdGENCmNvbWJpbmVkX2RhdGEkR2FyYWdlQ29uZCA8LSBhZGROQShjb21iaW5lZF9kYXRhJEdhcmFnZUNvbmQpDQpjb21iaW5lZF9kYXRhJEdhcmFnZVF1YWwgPC0gYWRkTkEoY29tYmluZWRfZGF0YSRHYXJhZ2VRdWFsKQ0KY29tYmluZWRfZGF0YSRHYXJhZ2VDb25kIDwtIGZhY3Rvcihjb21iaW5lZF9kYXRhJEdhcmFnZUNvbmQsIGxldmVscyA9IGMoIlBvIiwgIkZhIiwgIlRBIiwgIkdkIiwgIkV4IikpDQpjb21iaW5lZF9kYXRhJEdhcmFnZVF1YWwgPC0gZmFjdG9yKGNvbWJpbmVkX2RhdGEkR2FyYWdlUXVhbCwgbGV2ZWxzID0gYygiUG8iLCAiRmEiLCAiVEEiLCAiR2QiLCAiRXgiKSkNCmNvbWJpbmVkX2RhdGEkR2FyYWdlQ29uZCA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkR2FyYWdlQ29uZCkNCmNvbWJpbmVkX2RhdGEkR2FyYWdlUXVhbCA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkR2FyYWdlUXVhbCkNCg0KDQoNCiMgQ29udmVydCBOQSB2YWx1ZXMgdG8gZmFjdG9yIGxldmVscw0KY29tYmluZWRfZGF0YSRQb29sUUMgPC0gYWRkTkEoY29tYmluZWRfZGF0YSRQb29sUUMpDQpjb21iaW5lZF9kYXRhJEZpcmVwbGFjZVF1IDwtIGFkZE5BKGNvbWJpbmVkX2RhdGEkRmlyZXBsYWNlUXUpDQpjb21iaW5lZF9kYXRhJEhlYXRpbmdRQyA8LSBhZGROQShjb21iaW5lZF9kYXRhJEhlYXRpbmdRQykNCmNvbWJpbmVkX2RhdGEkS2l0Y2hlblF1YWwgPC0gYWRkTkEoY29tYmluZWRfZGF0YSRLaXRjaGVuUXVhbCkNCmNvbWJpbmVkX2RhdGEkQnNtdEV4cG9zdXJlIDwtIGFkZE5BKGNvbWJpbmVkX2RhdGEkQnNtdEV4cG9zdXJlKQ0KY29tYmluZWRfZGF0YSRQb29sUUMgPC0gZmFjdG9yKGNvbWJpbmVkX2RhdGEkUG9vbFFDLCBsZXZlbHMgPSBjKCJQbyIsICJGYSIsICJUQSIsICJHZCIsICJFeCIpKQ0KY29tYmluZWRfZGF0YSRGaXJlcGxhY2VRdSA8LSBmYWN0b3IoY29tYmluZWRfZGF0YSRGaXJlcGxhY2VRdSwgbGV2ZWxzID0gYygiUG8iLCAiRmEiLCAiVEEiLCAiR2QiLCAiRXgiKSkNCmNvbWJpbmVkX2RhdGEkSGVhdGluZ1FDIDwtIGZhY3Rvcihjb21iaW5lZF9kYXRhJEhlYXRpbmdRQywgbGV2ZWxzID0gYygiUG8iLCAiRmEiLCAiVEEiLCAiR2QiLCAiRXgiKSkNCmNvbWJpbmVkX2RhdGEkS2l0Y2hlblF1YWwgPC0gZmFjdG9yKGNvbWJpbmVkX2RhdGEkS2l0Y2hlblF1YWwsIGxldmVscyA9IGMoIlBvIiwgIkZhIiwgIlRBIiwgIkdkIiwgIkV4IikpDQpjb21iaW5lZF9kYXRhJEJzbXRFeHBvc3VyZSA8LSBmYWN0b3IoY29tYmluZWRfZGF0YSRCc210RXhwb3N1cmUsIGxldmVscyA9IGMoIk5vIiwgIk1uIiwgIkF2IiwgIkdkIikpDQpjb21iaW5lZF9kYXRhJFBvb2xRQyA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkUG9vbFFDKQ0KY29tYmluZWRfZGF0YSRGaXJlcGxhY2VRdSA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkRmlyZXBsYWNlUXUpDQpjb21iaW5lZF9kYXRhJEhlYXRpbmdRQyA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkSGVhdGluZ1FDKQ0KY29tYmluZWRfZGF0YSRLaXRjaGVuUXVhbCA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkS2l0Y2hlblF1YWwpDQpjb21iaW5lZF9kYXRhJEJzbXRFeHBvc3VyZSA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkQnNtdEV4cG9zdXJlKQ0KDQoNCg0KIyBDb252ZXJ0IE5BIHZhbHVlcyB0byBmYWN0b3IgbGV2ZWxzDQpjb21iaW5lZF9kYXRhJEJzbXRGaW5UeXBlMSA8LSBhZGROQShjb21iaW5lZF9kYXRhJEJzbXRGaW5UeXBlMSkNCmNvbWJpbmVkX2RhdGEkQnNtdEZpblR5cGUyIDwtIGFkZE5BKGNvbWJpbmVkX2RhdGEkQnNtdEZpblR5cGUyKQ0KY29tYmluZWRfZGF0YSRGZW5jZSA8LSBhZGROQShjb21iaW5lZF9kYXRhJEZlbmNlKQ0KY29tYmluZWRfZGF0YSRHYXJhZ2VGaW5pc2ggPC0gYWRkTkEoY29tYmluZWRfZGF0YSRHYXJhZ2VGaW5pc2gpDQpjb21iaW5lZF9kYXRhJEFsbGV5IDwtIGFkZE5BKGNvbWJpbmVkX2RhdGEkQWxsZXkpDQoNCiN0YWJsZShjb21iaW5lZF9kYXRhJEFsbGV5KQ0KDQpjb21iaW5lZF9kYXRhJEJzbXRGaW5UeXBlMSA8LSBmYWN0b3IoY29tYmluZWRfZGF0YSRCc210RmluVHlwZTEsIGxldmVscyA9IGMoIlVuZiIsICJMd1EiLCAiUmVjIiwgIkJMUSIsICJBTFEiLCAiR0xRIikpDQpjb21iaW5lZF9kYXRhJEJzbXRGaW5UeXBlMiA8LSBmYWN0b3IoY29tYmluZWRfZGF0YSRCc210RmluVHlwZTIsIGxldmVscyA9IGMoIlVuZiIsICJMd1EiLCAiUmVjIiwgIkJMUSIsICJBTFEiLCAiR0xRIikpDQpjb21iaW5lZF9kYXRhJENlbnRyYWxBaXIgPC0gZmFjdG9yKGNvbWJpbmVkX2RhdGEkQ2VudHJhbEFpciwgbGV2ZWxzID0gYygiTiIsICJZIikpDQpjb21iaW5lZF9kYXRhJEZlbmNlIDwtIGZhY3Rvcihjb21iaW5lZF9kYXRhJEZlbmNlLCBsZXZlbHMgPSBjKCJNbld3IiwgIkdkV28iLCAiTW5QcnYiLCAiR2RQcnYiKSkNCmNvbWJpbmVkX2RhdGEkR2FyYWdlRmluaXNoIDwtIGZhY3Rvcihjb21iaW5lZF9kYXRhJEdhcmFnZUZpbmlzaCwgbGV2ZWxzID0gYygiVW5mIiwgIlJGbiIsICJGaW4iKSkNCmNvbWJpbmVkX2RhdGEkQWxsZXkgPC0gZmFjdG9yKGNvbWJpbmVkX2RhdGEkQWxsZXksIGxldmVscyA9IGMoIkdydmwiLCAiUGF2ZSIpKQ0KY29tYmluZWRfZGF0YSRMb3RTaGFwZSA8LSBmYWN0b3IoY29tYmluZWRfZGF0YSRMb3RTaGFwZSwgbGV2ZWxzID0gYygiUmVnIiwgIklSMSIsICJJUjIiLCAiSVIzIikpDQpjb21iaW5lZF9kYXRhJExhbmRTbG9wZSA8LSBmYWN0b3IoY29tYmluZWRfZGF0YSRMYW5kU2xvcGUsIGxldmVscyA9IGMoIkd0bCIsICJNb2QiLCAiU2V2IikpDQoNCmNvbWJpbmVkX2RhdGEkQnNtdEZpblR5cGUxIDwtIGFzLm51bWVyaWMoY29tYmluZWRfZGF0YSRCc210RmluVHlwZTEpDQpjb21iaW5lZF9kYXRhJEJzbXRGaW5UeXBlMiA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkQnNtdEZpblR5cGUyKQ0KY29tYmluZWRfZGF0YSRDZW50cmFsQWlyIDwtIGFzLm51bWVyaWMoY29tYmluZWRfZGF0YSRDZW50cmFsQWlyKQ0KY29tYmluZWRfZGF0YSRGZW5jZSA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkRmVuY2UpDQpjb21iaW5lZF9kYXRhJEdhcmFnZUZpbmlzaCA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkR2FyYWdlRmluaXNoKQ0KY29tYmluZWRfZGF0YSRBbGxleSA8LSBhcy5udW1lcmljKGNvbWJpbmVkX2RhdGEkQWxsZXkpDQpjb21iaW5lZF9kYXRhJExvdFNoYXBlIDwtIGFzLm51bWVyaWMoY29tYmluZWRfZGF0YSRMb3RTaGFwZSkNCmNvbWJpbmVkX2RhdGEkTGFuZFNsb3BlIDwtIGFzLm51bWVyaWMoY29tYmluZWRfZGF0YSRMYW5kU2xvcGUpDQoNCg0KDQoNCm9yZGluYWxfY29scyA8LSBjKCdFeHRlclF1YWwnLCAnRXh0ZXJDb25kJywgJ0JzbXRRdWFsJywgJ0JzbXRDb25kJywgDQogICAgICAgICAgICAgICAgICAnR2FyYWdlQ29uZCcsICdHYXJhZ2VRdWFsJywgJ1Bvb2xRQycsICdGaXJlcGxhY2VRdScsIA0KICAgICAgICAgICAgICAgICAgJ0hlYXRpbmdRQycsICdLaXRjaGVuUXVhbCcsICdCc210RXhwb3N1cmUnLCAnQnNtdEZpblR5cGUxJywgDQogICAgICAgICAgICAgICAgJ0JzbXRGaW5UeXBlMicsICdDZW50cmFsQWlyJywgJ0ZlbmNlJywnR2FyYWdlRmluaXNoJywnQWxsZXknLCdMb3RTaGFwZScsJ0xhbmRTbG9wZScpDQoNCiN0YWJsZShkYXRhJEV4dGVyUXVhbCkNCg0KDQpjb21iaW5lZF9kYXRhW29yZGluYWxfY29sc10gPC0gbGFwcGx5KGNvbWJpbmVkX2RhdGFbb3JkaW5hbF9jb2xzXSwgZnVuY3Rpb24oeCkgcmVwbGFjZSh4LCBpcy5uYSh4KSwgMCkpDQoNCg0KDQoNCg0KIyBUcmFuc2Zvcm0gb3JkaW5hbCBjb2x1bW5zIGludG8gZmFjdG9ycyBhbmQgcmVwbGFjZSBOQSB3aXRoIDANCg0KI2RhdGFbb3JkaW5hbF9jb2xzXSA8LSBsYXBwbHkoZGF0YVtvcmRpbmFsX2NvbHNdLCBmdW5jdGlvbih4KSB7DQojICB4IDwtIGFzLmZhY3Rvcih4KQ0KIyAgbGV2ZWxzKHgpIDwtIGMobGV2ZWxzKHgpLCAiMCIpDQojIHhbaXMubmEoeCldIDwtICIwIg0KIyAgcmV0dXJuKHgpDQojIH0pDQoNCiMgQ2hlY2tpbmcgYWxsIGNoYXJhY3RlciBjb2x1bW5zDQojY29sbmFtZXMoZGF0YSlbY29sU3Vtcyhpcy5uYShkYXRhKSkgPiAwXQ0KDQoNCg0KDQojIFRocmVzaG9sZCBmb3IgJ3JhcmUnIG9ic2VydmF0aW9ucw0KbiA8LSAxMCANCg0KIyBMb29wIHRocm91Z2ggdGhlIGNoYXJhY3RlciBjb2x1bW5zDQpmb3IgKGNvbF9uYW1lIGluIGNvbG5hbWVzKGNvbWJpbmVkX2RhdGEpW3NhcHBseShjb21iaW5lZF9kYXRhLCBpcy5jaGFyYWN0ZXIpXSkgew0KICAjIENvbnZlcnQgcmFyZSBvYnNlcnZhdGlvbnMgdG8gJ090aGVyJw0KICBjb21iaW5lZF9kYXRhW1tjb2xfbmFtZV1dIDwtIGlmZWxzZShjb21iaW5lZF9kYXRhW1tjb2xfbmFtZV1dICVpbiUgbmFtZXMod2hpY2godGFibGUoY29tYmluZWRfZGF0YVtbY29sX25hbWVdXSkgPCBuKSksICJPdGhlciIsIGNvbWJpbmVkX2RhdGFbW2NvbF9uYW1lXV0pDQogIA0KICAjIENvbnZlcnQgY29sdW1uIHRvIGZhY3Rvcg0KICBjb21iaW5lZF9kYXRhW1tjb2xfbmFtZV1dIDwtIGFzLmZhY3Rvcihjb21iaW5lZF9kYXRhW1tjb2xfbmFtZV1dKQ0KDQogICMgQWRkIE5BIGFzIGEgbGV2ZWwgaWYgdGhlcmUgYXJlIGFueSBOQXMgaW4gdGhlIGNvbHVtbg0KICBpZihhbnkoaXMubmEoY29tYmluZWRfZGF0YVtbY29sX25hbWVdXSkpKSB7DQogICAgY29tYmluZWRfZGF0YVtbY29sX25hbWVdXSA8LSBhZGROQShjb21iaW5lZF9kYXRhW1tjb2xfbmFtZV1dKQ0KICAgIA0KICANCiAgfQ0KfQ0KDQojRGVsZXRpbmcgc29tZSBjb2x1bW5zDQojcmFyZV9sZXZlbF9mYWN0b3JzIDwtIHNhcHBseShkYXRhMiwgZnVuY3Rpb24oeCkgaXMuZmFjdG9yKHgpICYmIGFueSh0YWJsZSh4KSA8PSAyKSkNCiNwcmludChuYW1lcyhkYXRhMilbcmFyZV9sZXZlbF9mYWN0b3JzXSkNCg0KDQojZGF0YSRFbGVjdHJpY2FsPWFzLmNoYXJhY3RlcihkYXRhJEVsZWN0cmljYWwpDQojZGF0YSRFbGVjdHJpY2FsW2lzLm5hKGRhdGEkRWxlY3RyaWNhbCldIDwtICJPdGhlciINCiNkYXRhJEVsZWN0cmljYWw9YXMuZmFjdG9yKGRhdGEkRWxlY3RyaWNhbCkNCiNjbGFzcyhjb21iaW5lZF9kYXRhJEVsZWN0cmljYWwpDQoNCg0KDQojZGF0YSA8LSBkYXRhWywtd2hpY2gobmFtZXMoZGF0YSkgPT0gIlV0aWxpdGllcyIpXQ0KDQoNCiMgTm8gbW9yZSBtaXNzaW5nIHZhbHVlcywgb3JkaW5hcnkgdmFyaWFibGUgaGFzIGJlZW4gZmFjdG9yaXplZA0KDQpzdW0oaXMubmEoY29tYmluZWRfZGF0YSkpDQojdGFibGUoZGF0YSRNaXNjRmVhdHVyZSkNCiN0YWJsZShkYXRhJFN0cmVldCkNCiN0YWJsZShkYXRhJFV0aWxpdGllcykNCiN0YWJsZShkYXRhJENvbmRpdGlvbjIpDQojdGFibGUoZGF0YSRNaXNjRmVhdHVyZSkNCiN0YWJsZShkYXRhJEVsZWN0cmljYWwpDQoNCg0KDQoNCg0KDQpgYGANCg0KDQoNCg0KDQojIENoZWNraW5nIENvbGluZWFyaXR5IG9mIHRoZSBtb2RlbA0KDQpgYGB7cn0NCg0KI0RlbGV0aW5nICJUb3RhbEJzbXRTRiBvciBYMXN0RmxyU0YiICwgIkdhcmFnZUNhcnMgb3IgR2FyYWdlQXJlYSIgLCAiWWVhckJ1aWx0IG9yIEdhcmFnZVllYXJCdWlsdCIgLCAiRmlyZXBsYWNlcyIgb3IgIkZpcmVwbGFjZXNRdSIgLCAiR2FyYWdlQ29uZCIgb3IgR2FyYWdlUXUiLCAgIlBvb2xRQyBvciBQb29sQXJlYSINCg0KZGZfbnVtZXJpYyA8LSBjb21iaW5lZF9kYXRhW3NhcHBseShjb21iaW5lZF9kYXRhLCBpcy5udW1lcmljKV0NCg0KIyBDb21wdXRlIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgNCmNvcl9tYXRyaXggPC0gY29yKGRmX251bWVyaWMsIHVzZSA9ICJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiKQ0KDQojIENyZWF0ZSBhIGNvcnJlbGF0aW9uIHBsb3QNCmNvcnJwbG90KGNvcl9tYXRyaXgsIHR5cGUgPSAidXBwZXIiLCBvcmRlciA9ICJoY2x1c3QiLCANCiAgICAgICAgIHRsLmNvbCA9ICJibGFjayIsIHRsLnNydCA9IDQ1LCB0bC5jZXggPSAwLjUpDQoNCg0KIyBGaW5kIHBhaXJzIHdpdGggaGlnaCBjb3JyZWxhdGlvbg0KaGlnaF9jb3JyX2luZGljZXMgPC0gZmluZENvcnJlbGF0aW9uKGNvcl9tYXRyaXgsIGN1dG9mZiA9IDAuNykNCg0KIyBHZXQgY29sdW1uIG5hbWVzIGZyb20gaW5kaWNlcw0KaGlnaF9jb3JyX25hbWVzIDwtIGNvbG5hbWVzKGRmX251bWVyaWMpW2hpZ2hfY29ycl9pbmRpY2VzXQ0KDQojIFByaW50IHRoZSBjb2x1bW4gbmFtZXMNCnByaW50KGhpZ2hfY29ycl9uYW1lcykNCmBgYA0KRGVsZXRpbmcgIlRvdGFsQnNtdFNGIG9yIFgxc3RGbHJTRiIgLCAiR2FyYWdlQ2FycyBvciBHYXJhZ2VBcmVhIiAsICJZZWFyQnVpbHQgb3IgR2FyYWdlWWVhckJ1aWx0IiAsICJGaXJlcGxhY2VzIiBvciAiRmlyZXBsYWNlc1F1IiAsICJHYXJhZ2VDb25kIiBvciBHYXJhZ2VRdWFsIiAiUG9vbFFDIG9yIFBvb2xBcmVhIiwgIkJzbXRGaW5TRjEgb3IgQnNtdEZpblR5cGUxIu+8jCDigJxCc210RmluU0YyIG9yIEJzbXRGaW5UeXBlMiIgDQoNCiMgQ2hlY2tpbmcgZm9yIHJlZHVuZGVuY3kvIGRlbGV0aW5nIG5vaXNlIGluIHRoZSBkYXRhDQoNClJhcmUgT2JzZXJ2YXRpb24gcHJvdmlkZSB2ZXJ5IGxpdHRsZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGFuZCBtYXkgY2F1c2Ugbm9pc2UgaW4gdGhlIGRhdGEgc2V0Lg0KDQpgYGB7cn0NCnRhYmxlKGNvbWJpbmVkX2RhdGEkU3RyZWV0KQ0KdGFibGUoY29tYmluZWRfZGF0YSRVdGlsaXRpZXMpDQp0YWJsZShjb21iaW5lZF9kYXRhJENvbmRpdGlvbjIpDQp0YWJsZShjb21iaW5lZF9kYXRhJE1pc2NGZWF0dXJlKQ0KDQpjb21iaW5lZF9kYXRhIDwtIGNvbWJpbmVkX2RhdGFbLCAtd2hpY2gobmFtZXMoY29tYmluZWRfZGF0YSkgJWluJSBjKCdYMXN0RmxyU0YnLCAnR2FyYWdlQ2FycycsICdHYXJhZ2VZckJsdCcsJ0ZpcmVwbGFjZVF1JywnR2FyYWdlQ29uZCcsJ1Bvb2xRQycsJ0JzbXRGaW5UeXBlMScsJ0JzbXRGaW5UeXBlMicgLCdTdHJlZXQnLCAnVXRpbGl0aWVzJywgJ0NvbmRpdGlvbjInLCAnTWlzY0ZlYXR1cmUnLCAnQWxsZXknLCdGZW5jZScpKV0NCg0KDQojd3JpdGUuY3N2KGRhdGEyLGZpbGUgPSAnZGF0YTInKQ0KI2Zvcm11bGEobW9kZWwyKQ0KI2NvbG5hbWVzKGRhdGEyW3NhcHBseShkYXRhMixpcy5udW1lcmljKV0pDQp0YWJsZShjb21iaW5lZF9kYXRhJEZvdW5kYXRpb24pDQpgYGANCg0KDQojIENoZWNraW5nIGFzc3VtcHRpb24gZm9yIHJlZ3Jlc3Npb24gKGZ1bGwgbW9kZWwpDQoNCmBgYHtyLHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpkYXRhPWNvbWJpbmVkX2RhdGFbMToxNDYwLF0NCmRhdGEkU2FsZVByaWNlPXNhbGVwcmljZQ0KdGVzdCA9IGNvbWJpbmVkX2RhdGFbMTQ2MTpucm93KGNvbWJpbmVkX2RhdGEpLCBdDQoNCg0KDQoNCm1vZGVsID0gbG0oU2FsZVByaWNlIH4uLCBkYXRhID0gZGF0YSkNCg0KDQojIHJlc2lkdWFsIHBsb3RzIC8gSGlzdG9ncmFtIC8gUS1RIHBsb3QgLyBDYWxjdWxhdGUgQ29vaydzIGRpc3RhbmNlcyAvQ3JlYXRlIFJlc2lkdWFscyB2cyBMZXZlcmFnZSBwbG90DQpoaXN0b2dyYW0obW9kZWwkcmVzaWR1YWxzKQ0KcGxvdChtb2RlbCkNCg0KDQoNCiNMb29rIGZvciBpbmZsdWVudGlhbCBvYnNlcnZhdGlvbnMNCg0KI0xvb2tpbmcgYXQgb2JzZXJ2YXRpb24gMTI5OSw1MjQsIGRlbGV0ZSB0aGVtIGluIHRoZSBkYXRhDQpkYXRhPSBkYXRhWy1jKDEyOTksNTI0KSxdDQpyb3duYW1lcyhkYXRhKSA8LSBOVUxMDQojd3JpdGUuY3N2KGRhdGEsZmlsZSA9ICJ0cmFpbjEyMyIpDQojY29sbmFtZXMoZGF0YVtzYXBwbHkoY29tYmluZWRfZGF0YSwgaXMuZmFjdG9yKV0pDQpgYGANCg0KDQojIExvZ2dpbmcgU2FsZVByaWNlIHRvIHNlZSBpZiBpdCBmaXggdGhlIGNsdXN0ZXJyZWQgcmVzaWR1YWxzDQpgYGB7cix3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KZGF0YTI9ZGF0YQ0KZGF0YTIkU2FsZVByaWNlID0gbG9nKGRhdGEkU2FsZVByaWNlKQ0KbW9kZWwyID0gbG0oU2FsZVByaWNlfi4sIGRhdGEgPSBkYXRhMikNCiNzdW1tYXJ5KG1vZGVsMikNCnJlc2lkdWFsUGxvdChtb2RlbDIpDQojd3JpdGUuY3N2KGRhdGEyLGZpbGU9ImxvZ2RhdGEuY3N2Iixyb3cubmFtZXMgPSBGQUxTRSkNCg0KIyBDb21wYXJlIHRvIG1vZGVsMSh1bmxvZ2dlZCkgLCB0aGUgcmVzaWR1YWwgcGxvdHMgZm9ybXMgYSByYXRoZXIgcGVyZmVjdCByYW5kb20gY2xvdWQgZm9ybWF0aW9uIHdoaWNoIGlzIGlkZWFsDQojIEhpc3RvZ3JhbQ0KcmVzMj0gbW9kZWwyJHJlc2lkdWFscw0KaGlzdG9ncmFtKHJlczIpDQoNCnBsb3QobW9kZWwyKQ0KYGBgDQoNCg0KDQoNCg0KIyBQZXJmb3JtIGEgZm9yd2FyZC9iYWNrd2FyZC9zdGVwd2lzZSBzZWxlY3Rpb24gaW4gU0FTDQoNCiFbRGlhbm9zdGljc10odGFibGUucG5nKQ0KDQoNCg0KIyBCdWlsZCBjdXN0b20gcmVncmVzc2lvbiBtb2RlbCBpbiBTQVMNCg0KYGBge3J9DQptb2RlbF9mb3JtdWxhPSBsbShTYWxlUHJpY2UgfiBNU1pvbmluZzpHckxpdkFyZWErIExvdEFyZWE6QnNtdEZpblNGMStLaXRjaGVuQWJ2R3I6R2FyYWdlUXVhbCArR3JMaXZBcmVhOkxvdEFyZWErIExvdEFyZWEgKyBPdmVyYWxsUXVhbCArIE92ZXJhbGxDb25kICsgWWVhckJ1aWx0ICArIEJzbXRFeHBvc3VyZSArIEJzbXRGaW5TRjEgK0JzbXRGaW5TRjIgK0hlYXRpbmdRQytCc210VW5mU0YgKyBHckxpdkFyZWEgKyBIYWxmQmF0aCArIEtpdGNoZW5BYnZHciArIEtpdGNoZW5RdWFsICsgR2FyYWdlQXJlYSArIEdhcmFnZVF1YWwgKyBXb29kRGVja1NGICsNCiAgICAgICAgICAgICAgIFNjcmVlblBvcmNoICArIE1TWm9uaW5nICArIE5laWdoYm9yaG9vZCAgKyBCbGRnVHlwZSArDQogICAgICAgICAgICAgICBNYXNWbnJUeXBlICsgRm91bmRhdGlvbiArIEZ1bmN0aW9uYWwgKyBHYXJhZ2VUeXBlICArIFNhbGVDb25kaXRpb24rRmlyZXBsYWNlcywNCiAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhMikgICAgICAgICAgIA0KDQoNCg0KDQpgYGANCg0KDQojIFByZWRpdGlvbg0KYGBge3J9DQoNCnRhYmxlKGRhdGEkTVNab25pbmcpDQp0YWJsZSh0ZXN0JE1TWm9uaW5nKQ0KbGV2ZWxzKHRlc3QkTVNab25pbmcpW2lzLm5hKGxldmVscyh0ZXN0JE1TWm9uaW5nKSldIDwtICJSTCINCg0KDQp0YWJsZShkYXRhJEV4dGVyaW9yMXN0ICkNCnRhYmxlKHRlc3QkRXh0ZXJpb3Ixc3QgKQ0KbGV2ZWxzKHRlc3QkRXh0ZXJpb3Ixc3QpW2lzLm5hKGxldmVscyh0ZXN0JEV4dGVyaW9yMXN0KSldIDwtICJWaW55bFNkIg0KDQp0YWJsZShkYXRhJEZ1bmN0aW9uYWwgICkNCnRhYmxlKHRlc3QkRnVuY3Rpb25hbCAgKQ0KbGV2ZWxzKHRlc3QkRnVuY3Rpb25hbCApW2lzLm5hKGxldmVscyh0ZXN0JEZ1bmN0aW9uYWwgKSldIDwtICJUeXAiDQoNCnRhYmxlKGRhdGEkU2FsZVR5cGUgICApDQp0YWJsZSh0ZXN0JFNhbGVUeXBlICAgKQ0KbGV2ZWxzKHRlc3QkU2FsZVR5cGUgIClbaXMubmEobGV2ZWxzKHRlc3QkU2FsZVR5cGUgICkpXSA8LSAiV0QiDQojRm9yd2FyZA0KDQpsbV9wcmVkaWN0X21vZGVsPSBsbShTYWxlUHJpY2UgfiBNU1N1YkNsYXNzICsgTG90QXJlYSArIE92ZXJhbGxRdWFsICsgT3ZlcmFsbENvbmQgKyBZZWFyQnVpbHQgKyBNYXNWbnJBcmVhICsgRXh0ZXJRdWFsICsNCiAgICAgICAgICAgICAgIEJzbXRRdWFsICsgQnNtdENvbmQgKyBCc210RXhwb3N1cmUgKyBCc210RmluU0YxICsgVG90YWxCc210U0YgKyBHckxpdkFyZWEgKyBIYWxmQmF0aCArDQogICAgICAgICAgICAgICBCZWRyb29tQWJ2R3IgKyBLaXRjaGVuQWJ2R3IgKyBLaXRjaGVuUXVhbCArIEdhcmFnZUFyZWEgKyBHYXJhZ2VRdWFsICsgV29vZERlY2tTRiArDQogICAgICAgICAgICAgICBTY3JlZW5Qb3JjaCArIE1vU29sZCArIE1TWm9uaW5nICsgTG90Q29uZmlnICsgTmVpZ2hib3Job29kICsgQ29uZGl0aW9uMSArIEJsZGdUeXBlICsNCiAgICAgICAgICAgICAgIEV4dGVyaW9yMXN0ICsgTWFzVm5yVHlwZSArIEZvdW5kYXRpb24gKyBGdW5jdGlvbmFsICsgR2FyYWdlVHlwZSArIFBhdmVkRHJpdmUgKyBTYWxlQ29uZGl0aW9uLA0KICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEyKQ0KI3N1bW1hcnkobG1fcHJlZGljdF9tb2RlbCkNCg0KIA0KIA0KcHJlZGljaXRvbj1wcmVkaWN0KGxtX3ByZWRpY3RfbW9kZWwsbmV3ZGF0YSA9IHRlc3QpDQoNCg0KdGVzdCRTYWxlUHJpY2U9ZXhwKHByZWRpY2l0b24pDQpTdWJtaXNzaW9uX0Y9dGVzdFssYygiSWQiLCJTYWxlUHJpY2UiKV0NCg0KbWVhbl9zYWxlX3ByaWNlIDwtIG1lYW4oU3VibWlzc2lvbl9GJFNhbGVQcmljZSwgbmEucm0gPSBUUlVFKQ0KU3VibWlzc2lvbl9GJFNhbGVQcmljZVtpcy5uYShTdWJtaXNzaW9uX0YkU2FsZVByaWNlKV0gPC0gbWVhbl9zYWxlX3ByaWNlDQoNCnN1bShpcy5uYShwcmVkaWNpdG9uKSkNCndyaXRlLmNzdihTdWJtaXNzaW9uX0YsIGZpbGUgPSAnU3VibWlzc2lvbl9GLmNzdicsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KDQoNCg0KcGxvdChsbV9wcmVkaWN0X21vZGVsJHJlc2lkdWFscykNCnFxUGxvdChsbV9wcmVkaWN0X21vZGVsKQ0KaGlzdG9ncmFtKGxtX3ByZWRpY3RfbW9kZWwkcmVzaWR1YWxzKQ0KcGxvdChsbV9wcmVkaWN0X21vZGVsKQ0KDQoNCg0KDQojQmFja3dhcmQNCg0KbW9kZWxfZm9ybXVsYSA8LSBsbSggU2FsZVByaWNlIH4gTVNTdWJDbGFzcyArIExvdEZyb250YWdlICsgTG90QXJlYSArIExhbmRTbG9wZSArIE92ZXJhbGxRdWFsICsgT3ZlcmFsbENvbmQgKyBZZWFyQnVpbHQgKyBNYXNWbnJBcmVhICsgRXh0ZXJRdWFsICsgRXh0ZXJDb25kICsgQnNtdFF1YWwgKyBCc210Q29uZCArIEJzbXRFeHBvc3VyZSArIEJzbXRGaW5TRjEgKyBCc210RmluU0YyICsgQnNtdFVuZlNGICsgSGVhdGluZ1FDICsgWDJuZEZsclNGICsgTG93UXVhbEZpblNGICsgR3JMaXZBcmVhICsgRnVsbEJhdGggKyBIYWxmQmF0aCArIEJlZHJvb21BYnZHciArIEtpdGNoZW5BYnZHciArIEtpdGNoZW5RdWFsICsgVG90Um1zQWJ2R3JkICsgRmlyZXBsYWNlcyArIEdhcmFnZUFyZWEgKyBHYXJhZ2VRdWFsICsgV29vZERlY2tTRiArIE9wZW5Qb3JjaFNGICsgWDNTc25Qb3JjaCArIFNjcmVlblBvcmNoICsgUG9vbEFyZWEgKyBNb1NvbGQgKyBNU1pvbmluZyArIExhbmRDb250b3VyICsgTG90Q29uZmlnICsgTmVpZ2hib3Job29kICsgQ29uZGl0aW9uMSArIEJsZGdUeXBlICsgSG91c2VTdHlsZSArIFJvb2ZNYXRsICsgRXh0ZXJpb3Ixc3QgKyBNYXNWbnJUeXBlICsgRm91bmRhdGlvbiArIEZ1bmN0aW9uYWwgKyBHYXJhZ2VUeXBlICsgU2FsZVR5cGUgKyBTYWxlQ29uZGl0aW9uDQosZGF0YSA9IGRhdGEyKQ0KI3N1bW1hcnkobW9kZWxfZm9ybXVsYSkNCnByZWRpY2l0b249cHJlZGljdChtb2RlbF9mb3JtdWxhLG5ld2RhdGEgPSB0ZXN0KQ0KDQp0ZXN0JFNhbGVQcmljZT1leHAocHJlZGljaXRvbikNCnN1Ym1pc3Npb25fQmFja3dhcmQ9dGVzdFssYygiSWQiLCJTYWxlUHJpY2UiKV0NCg0KbWVhbl9zYWxlX3ByaWNlIDwtIG1lYW4oc3VibWlzc2lvbl9CYWNrd2FyZCRTYWxlUHJpY2UsIG5hLnJtID0gVFJVRSkNCnN1Ym1pc3Npb25fQmFja3dhcmQkU2FsZVByaWNlW2lzLm5hKHN1Ym1pc3Npb25fQmFja3dhcmQkU2FsZVByaWNlKV0gPC0gbWVhbl9zYWxlX3ByaWNlDQoNCnN1bShpcy5uYShwcmVkaWNpdG9uKSkNCndyaXRlLmNzdihzdWJtaXNzaW9uX0JhY2t3YXJkLCBmaWxlID0gJ3N1Ym1pc3Npb25fQmFja3dhcmQuY3N2Jywgcm93Lm5hbWVzID0gRkFMU0UpDQoNCg0KcGxvdChtb2RlbF9mb3JtdWxhJHJlc2lkdWFscykNCnFxUGxvdChtb2RlbF9mb3JtdWxhKQ0KaGlzdG9ncmFtKG1vZGVsX2Zvcm11bGEkcmVzaWR1YWxzKQ0KcGxvdChtb2RlbF9mb3JtdWxhKQ0KDQojc3RlcHdpc2UNCg0KbW9kZWxfZm9ybXVsYSA8LSBsbShTYWxlUHJpY2UgfiBNU1N1YkNsYXNzICsgTG90RnJvbnRhZ2UgKyBMb3RBcmVhICsgTGFuZFNsb3BlICsgT3ZlcmFsbFF1YWwgKyBPdmVyYWxsQ29uZCArIFllYXJCdWlsdCArIE1hc1ZuckFyZWEgKyBFeHRlclF1YWwgKyBFeHRlckNvbmQgKyBCc210UXVhbCArIEJzbXRDb25kICsgQnNtdEV4cG9zdXJlICsgQnNtdEZpblNGMSArIEJzbXRGaW5TRjIgKyBUb3RhbEJzbXRTRiArIEdyTGl2QXJlYSArIEJlZHJvb21BYnZHciArIEtpdGNoZW5BYnZHciArIEtpdGNoZW5RdWFsICsgR2FyYWdlQXJlYSArIEdhcmFnZVF1YWwgKyBXb29kRGVja1NGICsgT3BlblBvcmNoU0YgKyBNb1NvbGQgKyBNU1pvbmluZyArIExvdENvbmZpZyArIE5laWdoYm9yaG9vZCArIENvbmRpdGlvbjEgKyBCbGRnVHlwZSArIEV4dGVyaW9yMXN0ICsgTWFzVm5yVHlwZSArIEZ1bmN0aW9uYWwgKyBHYXJhZ2VUeXBlICsgUGF2ZWREcml2ZSArIFNhbGVDb25kaXRpb24sZGF0YSA9IGRhdGEyKQ0KI3N1bW1hcnkobW9kZWxfZm9ybXVsYSkNCg0KcHJlZGljaXRvbj1wcmVkaWN0KG1vZGVsX2Zvcm11bGEsbmV3ZGF0YSA9IHRlc3QpDQoNCnRlc3QkU2FsZVByaWNlPWV4cChwcmVkaWNpdG9uKQ0Kc3VibWlzc2lvbl9zdGVwd2lzZT10ZXN0WyxjKCJJZCIsIlNhbGVQcmljZSIpXQ0KDQptZWFuX3NhbGVfcHJpY2UgPC0gbWVhbihzdWJtaXNzaW9uX3N0ZXB3aXNlJFNhbGVQcmljZSwgbmEucm0gPSBUUlVFKQ0Kc3VibWlzc2lvbl9zdGVwd2lzZSRTYWxlUHJpY2VbaXMubmEoc3VibWlzc2lvbl9zdGVwd2lzZSRTYWxlUHJpY2UpXSA8LSBtZWFuX3NhbGVfcHJpY2UNCg0Kc3VtKGlzLm5hKHByZWRpY2l0b24pKQ0Kd3JpdGUuY3N2KHN1Ym1pc3Npb25fc3RlcHdpc2UsIGZpbGUgPSAnc3VibWlzc2lvbl9zdGVwd2lzZS5jc3YnLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KcGxvdChtb2RlbF9mb3JtdWxhJHJlc2lkdWFscykNCnFxUGxvdChtb2RlbF9mb3JtdWxhKQ0KaGlzdG9ncmFtKG1vZGVsX2Zvcm11bGEkcmVzaWR1YWxzKQ0KcGxvdChtb2RlbF9mb3JtdWxhKQ0KI0N1c3RvbQ0KDQoNCg0KbW9kZWxfZm9ybXVsYT0gbG0oU2FsZVByaWNlIH4gTVNab25pbmc6R3JMaXZBcmVhKyBMb3RBcmVhOkJzbXRGaW5TRjErS2l0Y2hlbkFidkdyOkdhcmFnZVF1YWwgK0dyTGl2QXJlYTpMb3RBcmVhKyBMb3RBcmVhICsgT3ZlcmFsbFF1YWwgKyBPdmVyYWxsQ29uZCArIFllYXJCdWlsdCAgKyBCc210RXhwb3N1cmUgKyBCc210RmluU0YxICtCc210RmluU0YyICtIZWF0aW5nUUMrQnNtdFVuZlNGICsgR3JMaXZBcmVhICsgSGFsZkJhdGggKyBLaXRjaGVuQWJ2R3IgKyBLaXRjaGVuUXVhbCArIEdhcmFnZUFyZWEgKyBHYXJhZ2VRdWFsICsgV29vZERlY2tTRiArDQogICAgICAgICAgICAgICBTY3JlZW5Qb3JjaCAgKyBNU1pvbmluZyAgKyBOZWlnaGJvcmhvb2QgICsgQmxkZ1R5cGUgKw0KICAgICAgICAgICAgICAgTWFzVm5yVHlwZSArIEZvdW5kYXRpb24gKyBGdW5jdGlvbmFsICsgR2FyYWdlVHlwZSAgKyBTYWxlQ29uZGl0aW9uK0ZpcmVwbGFjZXMsDQogICAgICAgICAgICAgICBkYXRhID0gZGF0YTIpICAgICAgICAgICANCiNzdW1tYXJ5KG1vZGVsX2Zvcm11bGEpDQoNCiANCnByZWRpY2l0b249cHJlZGljdChtb2RlbF9mb3JtdWxhLG5ld2RhdGEgPSB0ZXN0KSAgDQoNCnRlc3QkU2FsZVByaWNlPWV4cChwcmVkaWNpdG9uKQ0Kc3VibWlzc2lvbl9DdXN0PXRlc3RbLGMoIklkIiwiU2FsZVByaWNlIildDQoNCm1lYW5fc2FsZV9wcmljZSA8LSBtZWFuKHN1Ym1pc3Npb25fQ3VzdCRTYWxlUHJpY2UsIG5hLnJtID0gVFJVRSkNCnN1Ym1pc3Npb25fQ3VzdCRTYWxlUHJpY2VbaXMubmEoc3VibWlzc2lvbl9DdXN0JFNhbGVQcmljZSldIDwtIG1lYW5fc2FsZV9wcmljZQ0KDQpzdW0oaXMubmEocHJlZGljaXRvbikpDQp3cml0ZS5jc3Yoc3VibWlzc2lvbl9DdXN0LCBmaWxlID0gJ3N1Ym1pc3Npb25fQ3VzdC5jc3YnLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KcGxvdChtb2RlbF9mb3JtdWxhKQ0KcGxvdChtb2RlbF9mb3JtdWxhJHJlc2lkdWFscykNCmhpc3RvZ3JhbShtb2RlbF9mb3JtdWxhJHJlc2lkdWFscykNCg0KDQojdHJpYWwyDQoNCm1vZGVsX2Zvcm11bGE9IGxtKFNhbGVQcmljZSB+IChZZWFyQnVpbHQ6U2NyZWVuUG9yY2grTG90QXJlYTpUb3RhbEJzbXRTRitLaXRjaGVuQWJ2R3I6R2FyYWdlUXVhbCArR3JMaXZBcmVhOkxvdEFyZWErIExvdEFyZWEgKyBPdmVyYWxsUXVhbCArIE92ZXJhbGxDb25kICsgWWVhckJ1aWx0ICArIEJzbXRFeHBvc3VyZSArIEJzbXRGaW5TRjEgK0JzbXRGaW5TRjIgK0hlYXRpbmdRQytCc210VW5mU0YgKyBHckxpdkFyZWEgKyBIYWxmQmF0aCArIEtpdGNoZW5BYnZHciArIEtpdGNoZW5RdWFsICsgR2FyYWdlQXJlYSArIEdhcmFnZVF1YWwgKyBXb29kRGVja1NGICsNCiAgICAgICAgICAgICAgIFNjcmVlblBvcmNoICArIE1TWm9uaW5nICArIE5laWdoYm9yaG9vZCAgKyBCbGRnVHlwZSArDQogICAgICAgICAgICAgICBNYXNWbnJUeXBlICsgRm91bmRhdGlvbiArIEZ1bmN0aW9uYWwgKyBHYXJhZ2VUeXBlICArIFNhbGVDb25kaXRpb24rRmlyZXBsYWNlcyleMiwNCiAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhMikgIA0KI3N1bW1hcnkobW9kZWxfZm9ybXVsYSkNCg0KcHJlZGljaXRvbj1wcmVkaWN0KG1vZGVsX2Zvcm11bGEsbmV3ZGF0YSA9IHRlc3QpICANCg0KdGVzdCRTYWxlUHJpY2U9ZXhwKHByZWRpY2l0b24pDQpzdWJtaXNzaW9uX0N1c3Q9dGVzdFssYygiSWQiLCJTYWxlUHJpY2UiKV0NCg0KbWVhbl9zYWxlX3ByaWNlIDwtIG1lYW4oc3VibWlzc2lvbl9DdXN0JFNhbGVQcmljZSwgbmEucm0gPSBUUlVFKQ0Kc3VibWlzc2lvbl9DdXN0JFNhbGVQcmljZVtpcy5uYShzdWJtaXNzaW9uX0N1c3QkU2FsZVByaWNlKV0gPC0gbWVhbl9zYWxlX3ByaWNlDQoNCnN1bShpcy5uYShwcmVkaWNpdG9uKSkNCndyaXRlLmNzdihzdWJtaXNzaW9uX0N1c3QsIGZpbGUgPSAnc3VibWlzc2lvbl9DdXN0LmNzdicsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KDQoNCmBgYA0KDQoNCg0KDQojIEV4YW1lbiByZWxhdGlvbnNoaXAgaW4gU2FsZXMgcHJpY2UgaW4gbmVpZ2hib3Job29kICdOQW1lcycsICdFZHdhcmRzJywgJ0Jya1NpZGUnIA0KYGBge3Isd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCg0KZGF0YT0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9hbmlzaGthcGV0ZXIvU3RhdDFQcm9qZWN0L21haW4vdHJhaW4uY3N2IikNCg0KIyBNb2RlbCB3aXRob3V0IEludGVyYWN0aW9uIFZhcmlhYmxlIA0KZmlsdGVyZWRfbmVpZ2hib3Job29kID0gZGF0YSAlPiUgZmlsdGVyIChOZWlnaGJvcmhvb2QgJWluJSBjKCdOQW1lcycsICdFZHdhcmRzJywgJ0Jya1NpZGUnKSkNCg0KZmlsdGVyZWRfbmVpZ2hib3Job29kX21vZGVsPSBsbShTYWxlUHJpY2UgfiBHckxpdkFyZWEsIGRhdGEgPSBmaWx0ZXJlZF9uZWlnaGJvcmhvb2QpDQojc3VtbWFyeShmaWx0ZXJlZF9uZWlnaGJvcmhvb2RfbW9kZWwpDQoNCiMgQ2hlY2sgQXNzdW1wdGlvbnMgTW9kZWwgV2l0aG91dCBJbmRpY2F0b3IgYW5kIEludGVyYWN0aW9uIFZhcmlhYmxlICANCnBsb3QoZmlsdGVyZWRfbmVpZ2hib3Job29kX21vZGVsKQ0KDQpoaXN0b2dyYW0oZmlsdGVyZWRfbmVpZ2hib3Job29kX21vZGVsJHJlc2lkdWFscykNCg0KZ2dwbG90KGZpbHRlcmVkX25laWdoYm9yaG9vZCxhZXMoeCA9R3JMaXZBcmVhICwgeSA9U2FsZVByaWNlICkpICsgDQogIGdlb21fcG9pbnQoKSArDQogIGdndGl0bGUoIlNjYXR0ZXJQbG90IG9mIFNhbGVQcmljZSB2cyBHckxpdkFyZWEiKSANCg0KIyBSZXNpZHVhbCBwbG90IGNsdXN0ZXJlZCwgdXNpbmcgbG9nLWxvZyBtZXRob2QgdG8gdHJhbnNmb3JtIHRoZSBkYXRhc2V0DQoNCiMgTG9nIGxvZyBUcmFuc2Zvcm0gdG8gZGF0YSANCmRhdGEzPWRhdGENCmRhdGEzJFNhbGVQcmljZSA9IGxvZyhkYXRhJFNhbGVQcmljZSkNCmRhdGEzJEdyTGl2QXJlYSA9IGxvZyhkYXRhJEdyTGl2QXJlYSkNCg0KIyBmaWx0ZXIgdGhlIGxvZ2dlZCBkYXRhIHRvIG9ubHkgaW5jbHVkZSB0aGUgMyBuZWlnaGJvcmhvb2RzIG9mIGludGVyZXN0DQpmaWx0ZXJlZF9kYXRhMiA8LSBkYXRhMyAlPiUgZmlsdGVyKE5laWdoYm9yaG9vZCAlaW4lIGMoJ05BbWVzJywgJ0Vkd2FyZHMnLCAnQnJrU2lkZScpKQ0KDQojIGJ1aWxkIG1vZGVsIG9uIGxvZyBkYXRhIHdpdGhvdXQgaW50ZXJhY3Rpb24gYW5kIGluZGljYXRvciB2YXINCmZpbHRlcmVkX2RhdGEyX21vZGVsID0gbG0oU2FsZVByaWNlIH4gR3JMaXZBcmVhLCBkYXRhID0gZmlsdGVyZWRfZGF0YTIpDQojc3VtbWFyeShmaWx0ZXJlZF9kYXRhMl9tb2RlbCkNCg0KIyBDaGVja2luZyBBc3N1bXB0aW9ucyANCmdncGxvdChmaWx0ZXJlZF9kYXRhMixhZXMoeCA9R3JMaXZBcmVhICwgeSA9U2FsZVByaWNlICkpICsNCiAgZ2VvbV9wb2ludCgpK2dndGl0bGUoIlNjYXR0ZXJQbG90IG9mIExvZyhTYWxlUHJpY2UpIHZzIExvZyhHckxpdkFyZWEpIikgKyANCiAgeGxhYigiTG9nKEdyTGl2QXJlYSkiKSArDQogIHlsYWIoIkxvZyhTYWxlUHJpY2UpIikNCg0KaGlzdChmaWx0ZXJlZF9kYXRhMl9tb2RlbCRyZXNpZHVhbHMpDQoNCnBsb3QoZmlsdGVyZWRfZGF0YTJfbW9kZWwpDQoNCg0KIyBDb25maWRlbmNlIEludGVydmFsIGZvciBMb2cgTW9kZWwgd2l0aG91dCBJbnRlcmFjdGlvbiBvciBJbmRpY2F0b3INCmNvbmZpbnQoZmlsdGVyZWRfZGF0YTJfbW9kZWwpDQoNCnBsb3QoZmlsdGVyZWRfZGF0YTIkR3JMaXZBcmVhLCBmaWx0ZXJlZF9kYXRhMiRTYWxlUHJpY2UsIA0KICAgICBtYWluPSJTY2F0dGVycGxvdCB3aXRoIFJlZ3Jlc3Npb24gTGluZSIsIA0KICAgICB4bGFiPSJBYm92ZSBncmFkZSAoZ3JvdW5kKSBsaXZpbmcgYXJlYSBzcXVhcmUgZmVldCAoR3JMaXZBcmVhKSIsIA0KICAgICB5bGFiPSJTYWxlIFByaWNlIChTYWxlUHJpY2UpIiwgcGNoPTE5LCBmcmFtZT1GQUxTRSwgY29sPSJibHVlIikrDQogIGFibGluZShmaWx0ZXJlZF9kYXRhMl9tb2RlbCwgY29sPSJyZWQiKQ0KDQoNCmBgYA0KIyMjIyBUaGVyZWZvcmUgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgcHJlZGljdGluZyBTYWxlUHJpY2UgdXNpbmcgR3JsaXZBcmVhIGlzIA0KU2FsZVByaWNlID0gNy41ODQzNyArIDAuNTkyMzAgKiBHcmxpdkFyZWENCg0KIyBBZGRpbmcgSW5kaWNhdG9yIFZhcmlhYmxlIA0KYGBge3J9DQojIEFkZGluZyBJbmRpY2F0b3IgVmFyaWFibGUgDQpmaWx0ZXJlZF9kYXRhMl9tb2RlbDMgPC0gbG0oU2FsZVByaWNlIH4gIEdyTGl2QXJlYSArIE5laWdoYm9yaG9vZCwgZGF0YSA9IGZpbHRlcmVkX2RhdGEyKQ0KI3N1bW1hcnkoZmlsdGVyZWRfZGF0YTJfbW9kZWwzKQ0KDQpgYGANCg0KDQojIEFkZGluZyBpbnRlcmFjdGlvbiB2YXJpYWJsZXMNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KDQojIEZpdCB0aGUgbW9kZWwNCmZpbHRlcmVkX2RhdGEyX21vZGVsMiA8LSBsbShTYWxlUHJpY2UgfiAgR3JMaXZBcmVhICsgR3JMaXZBcmVhICogTmVpZ2hib3Job29kLCBkYXRhID0gZmlsdGVyZWRfZGF0YTIpDQoNCiMgU3VtbWFyeSBvZiB0aGUgbW9kZWwNCiNzdW1tYXJ5KGZpbHRlcmVkX2RhdGEyX21vZGVsMikNCg0KIyBDb25maWRlbmNlIGludGVydmFscw0KY29uZmludChmaWx0ZXJlZF9kYXRhMl9tb2RlbDIpDQoNCg0KIyBSZXNpZHVhbHMgaGlzdG9ncmFtDQpoaXN0b2dyYW0gPC0gZ2dwbG90KGZpbHRlcmVkX2RhdGEyX21vZGVsMiwgYWVzKHg9cmVzaWR1YWxzKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0xLCBjb2xvcj0iYmxhY2siLCBmaWxsPSJ3aGl0ZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh4PSJSZXNpZHVhbHMiLCB5PSJGcmVxdWVuY3kiLCB0aXRsZT0iSGlzdG9ncmFtIG9mIFJlc2lkdWFscyIpDQoNCiMgTW9kZWwgZGlhZ25vc3RpY3MNCnBsb3RfZGlhZyA8LSBwbG90KGZpbHRlcmVkX2RhdGEyX21vZGVsMiwgZGlhZ25vc3RpYyA9IFRSVUUpDQoNCg0KIyBNb2RlbCBDb2VmZmljaWVudHMNCm1vZGVsX2NvZWYgPC0gY29lZihmaWx0ZXJlZF9kYXRhMl9tb2RlbDIpDQpgYGANCg0KIyMgQW5vdmEgQW5hbHlzaXMgDQpgYGB7cn0NCiNBTk9WQSBmb3IgbW9kZWwgd2l0aCBOZWlnaGJvcmhvb2QgYXMgSW50ZXJhY3Rpb24gVmFyaWFibGUgDQphbm92YShmaWx0ZXJlZF9kYXRhMl9tb2RlbDMpDQoNCiNBTk9WQSBmb3IgbW9kZWwgd2l0aCBOZWlnaGJvcmhvb2QgYXMgSW5kaWNhdG9yIFZhcmlhYmxlIA0KYW5vdmEoZmlsdGVyZWRfZGF0YTJfbW9kZWwyKQ0KDQojQU5PVkEgZm9yIG1vZGVsIHdpdGhvdXQgTmVpZ2hib3Job29kICANCmFub3ZhKGZpbHRlcmVkX2RhdGEyX21vZGVsKQ0KDQoxIC0gcGYoNjguMDI5NzI5NzMsMiwzNzcpDQoNCjEgLSBwZig4LjY0MTg5MTg5MiwyLDM3NykNCg0KDQpgYGANCg0KDQojIE1vZGVsIHdpdGggSW50ZXJhY3Rpb24gU3VtbWFyaWVzIA0KDQpGb3Igb3VyIGJlc3QgcGVyZm9ybWluZyBtb2RlbCB3ZSBoYWQgIzEyODggb24gS2FnZ2xlLCBZYWghDQohW0RpYW5vc3RpY3NdKGthZ2dsZXNjb3JlLnBuZykNCg0KIyMjIyBGb3IgZWFjaCBuZWlnaGJvcmhvb2QsIHRoZSByZWdyZXNzaW9uIG1vZGVsIHByZWRpY3RpbmcgU2FsZVByaWNlIHVzaW5nIEdyTGl2QXJlYSBpcyBnaXZlbiBieToNCg0KIyMjIyBOZWlnaGJvcmhvb2QgJ0Jya1NpZGUnOg0KDQpsb2dTYWxlUHJpY2UgPSAgNS45MTI5MiArIDAuODE5NjUqbG9nR3JMaXZBcmVhDQoNCiMjIyMjIEludGVycHJldGF0aW9uIG9mIHRoZSBDb2VmZmljaWVudHMgDQpFdmVyeSB0aW1lIHRoZSBzcXVhcmUgZm9vdGFnZSBvZiB0aGUgbGl2aW5nIGFyZWEgZG91YmxlcywgdGhlcmUgaXMgYW4gZXN0aW1hdGVkIG11bHRpcGxpY2F0aXZlIGluY3JlYXNlIG9mIDEuNzY0OTc3NzU0MzYgKGFib3V0IDc2LjUlIGluY3JlYXNlKSBpbiB0aGUgbWVkaWFuIFNhbGUgUHJpY2UuICANCg0KV2hlbiB0aGUgc3F1YXJlIGZvb3RhZ2Ugb2YgdGhlIGxpdmluZyBhcmVhIGlzIDAsIHRoZSBlc3RpbWF0ZWQgbWVkaWFuIFNhbGVQcmljZSAzNjkuNzg0MzUuIA0KDQojIyMjIyBJbnRlcnByZXRhdGlvbiBvZiBDb25maWRlbmNlIEludGVydmFscyAgIA0KRXZlcnkgdGltZSB0aGUgc3F1YXJlIGZvb3RhZ2Ugb2YgdGhlIGxpdmluZyBhcmVhIGRvdWJsZXMsIHRoZSBlc3RpbWF0ZWQgbXVsdGlwbGljYXRpdmUgaW5jcmVhc2UgaW4gbWVkaWFuIFNhbGVzIFByaWNlIGZvciBCcm9va2VzaWRlIGlzIGJldHdlZW4gMS42MDA4MTQ3ODgyOSBhbmQgMS45NDU5NzAzMTE1Ni4gDQoNCldoZW4gdGhlIHNxdWFyZSBmb290YWdlIG9mIHRoZSBsaXZpbmcgYXJlYSBpcyAwLiwgdGhlIGVzdGltYXRlZCBtZWRpYW4gU2FsZSBQcmljZSBpcyBiZXR3ZWVuIDEzNy4xMDYzOTA4NSBhbmQgOTk3LjMzMjU4NDkwOCBpbiBCcm9va3NpZGUgbmVpZ2hib3Job29kLiAgDQoNCg0KIyMjIyBOZWlnaGJvcmhvb2QgJ05BbWVzJzoNCmxvZ1NhbGVQcmljZSA9IDcuNzQ3ODQgKyAwLjQ3MzAzKmxvZ0dyTGl2QXJlYQ0KDQoNCiMjIyMjIEludGVycHJldGF0aW9uIG9mIHRoZSBDb2VmZmljaWVudHMgDQpFdmVyeSB0aW1lIHRoZSBzcXVhcmUgZm9vdGFnZSBvZiB0aGUgbGl2aW5nIGFyZWEgZG91YmxlcywgdGhlcmUgaXMgYW4gZXN0aW1hdGVkIG11bHRpcGxpY2F0aXZlIGluY3JlYXNlIG9mIDEuMzg4MDIxNTgxODEsIChhYm91dCAzOC44JSBpbmNyZWFzZSkgaW4gdGhlIG1lZGlhbiBTYWxlIFByaWNlLiAgDQoNCldoZW4gdGhlIHNxdWFyZSBmb290YWdlIG9mIHRoZSBsaXZpbmcgYXJlYSBpcyAwLCB0aGUgZXN0aW1hdGVkIG1lZGlhbiBTYWxlUHJpY2UgNDg3OS4xNjgwMzY1NS4gDQoNCiMjIyMjIEludGVycHJldGF0aW9uIG9mIENvbmZpZGVuY2UgSW50ZXJ2YWxzICAgDQpXaGVuIHRoZSBzcXVhcmUgZm9vdGFnZSBvZiB0aGUgbGl2aW5nIGFyZWEgaXMgMCwgdGhlIGVzdGltYXRlZCBtZWRpYW4gU2FsZVByaWNlIDQ4NzkuMTY4MDM2NTUgLiANCg0KV2hlbiB0aGUgc3F1YXJlIGZvb3RhZ2Ugb2YgdGhlIGxpdmluZyBhcmVhIGlzIDAsIHRoZSBlc3RpbWF0ZWQgbWVkaWFuIFNhbGUgUHJpY2UgaXMgYmV0d2VlbiA1NTYuMTQ2NDE3MjcyIGFuZCA0MjgwNS41Nzc5OTIzIGluIE5vcnRoIEFtZXMgbmVpZ2hib3Job29kLiANCiANCg0KDQojIyMjIE5laWdoYm9yaG9vZCAnRWR3YXJkcyc6DQpsb2dTYWxlUHJpY2UgPSA4LjAwNjUxICsgMC41MTk2NyAqbG9nR3JMaXZBcmVhDQoNCiMjIyMjIEludGVycHJldGF0aW9uIG9mIHRoZSBDb2VmZmljaWVudHMgDQpFdmVyeSB0aW1lIHRoZSBzcXVhcmUgZm9vdGFnZSBvZiB0aGUgbGl2aW5nIGFyZWEgZG91YmxlcywgdGhlcmUgaXMgYW4gZXN0aW1hdGVkIG11bHRpcGxpY2F0aXZlIGluY3JlYXNlIG9mIDEuNDMzNjA3NDEwNSAoYWJvdXQgNDMuMzYlIGluY3JlYXNlKSBpbiB0aGUgbWVkaWFuIFNhbGUgUHJpY2UuICANCg0KV2hlbiB0aGUgc3F1YXJlIGZvb3RhZ2Ugb2YgdGhlIGxpdmluZyBhcmVhIGlzIDAsIHRoZSBlc3RpbWF0ZWQgbWVkaWFuIFNhbGUgUHJpY2UgMzAwMC40MjczMjc0OC4gIA0KDQojIyMjIyBDb25maWRlbmNlIEludGVydmFscyBhbmQgSW50ZXJwcmV0YXRpb24gDQoNCldoZW4gdGhlIHNxdWFyZSBmb290YWdlIG9mIHRoZSBsaXZpbmcgYXJlYSBpcyAwLCB0aGUgZXN0aW1hdGVkIG1lZGlhbiBTYWxlIFByaWNlIGlzIGJldHdlZW4gMzEyLjQxNjMzMzMzNSBhbmQgMjg4MTUuNzU2MDA0IGZvciBob3VzZXMgaW4gdGhlIEVkd2FyZHMgTmVpZ2hib3Job29kLiANCg0KRXZlcnkgdGltZSB0aGUgc3F1YXJlIGZvb3RhZ2Ugb2YgdGhlIGxpdmluZyBhcmVhIGRvdWJsZXMsIHRoZSBlc3RpbWF0ZWQgbXVsdGlwbGljYXRpdmUgaW5jcmVhc2UgaW4gbWVkaWFuIFNhbGVzIFByaWNlIGZvciBFZHdhcmRzIE5laWdoYm9yaG9vZCBpcyBiZXR3ZWVuIDEuMTQ4Mjc3MzEyOTkgYW5kIDEuNzg5ODgwNjYwOTQuIA0KDQoNCg0KDQoNCg0KZmlsdGVyZWRfZGF0YTINCmxpYnJhcnkoZ2dwbG90MikNCmZpbHRlcmVkX25laWdoYm9yaG9vZCAlPiUgDQogIGZpbHRlcihOZWlnaGJvcmhvb2QgPT0gIkJya1NpZGUiKSAlPiUgDQogIGdncGxvdChhZXMoeD1HckxpdkFyZWEsIHkgPSBTYWxlUHJpY2UpKSArIA0KICBnZW9tX3BvaW50KCBjb2xvciA9ICJzdGVlbGJsdWUiKSArIA0KICBnZ3RpdGxlKCJTYWxlIFByaWNlIHZzIExpdmluZyBBcmVhIFNxLkZ0IGluIEJyb29rc2lkZSIpICsNCiAgeGxhYigiU3F1YXJlIEZvb3RhZ2Ugb2YgTGl2aW5nIEFyZWEiKSArDQogIHlsYWIoIlNhbGVzIFByaWNlIGluIERvbGxhcnMiKQ0KDQoNCmZpbHRlcmVkX25laWdoYm9yaG9vZCAlPiUgDQogIGZpbHRlcihOZWlnaGJvcmhvb2QgPT0gIkVkd2FyZHMiKSAlPiUgDQogIGdncGxvdChhZXMoeD1HckxpdkFyZWEsIHkgPSBTYWxlUHJpY2UpKSArIA0KICBnZW9tX3BvaW50KCBjb2xvciA9ICJzdGVlbGJsdWUiKSArIA0KICBnZ3RpdGxlKCJTYWxlIFByaWNlIHZzIExpdmluZyBBcmVhIFNxLkZ0IGluIEVkd2FyZHMiKSArDQogIHhsYWIoIlNxdWFyZSBGb290YWdlIG9mIExpdmluZyBBcmVhIikgKw0KICB5bGFiKCJTYWxlcyBQcmljZSBpbiBEb2xsYXJzIikNCg0KZmlsdGVyZWRfbmVpZ2hib3Job29kICU+JSANCiAgZmlsdGVyKE5laWdoYm9yaG9vZCA9PSAiTkFtZXMiKSAlPiUgDQogIGdncGxvdChhZXMoeD1HckxpdkFyZWEsIHkgPSBTYWxlUHJpY2UpKSArIA0KICBnZW9tX3BvaW50KGNvbG9yID0gInN0ZWVsYmx1ZSIpICsgDQogIGdndGl0bGUoIlNhbGUgUHJpY2UgdnMgTGl2aW5nIEFyZWEgU3EuRnQgaW4gTm9ydGggQW1lcyIpICsNCiAgeGxhYigiU3F1YXJlIEZvb3RhZ2Ugb2YgTGl2aW5nIEFyZWEiKSArDQogIHlsYWIoIlNhbGVzIFByaWNlIGluIERvbGxhcnMiKQ0KDQoNCg0KDQoNCg==